package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.zzyl.base.PageBean;
import com.zzyl.dto.BillPageQueryDto;
import com.zzyl.entity.*;
import com.zzyl.enums.BillType;
import com.zzyl.mapper.BillMapper;
import com.zzyl.mapper.MemberElderMapper;
import com.zzyl.mapper.OrderMapper;
import com.zzyl.mapper.PrepaidRechargeRecordMapper;
import com.zzyl.service.BillService;
import com.zzyl.service.MemberService;
import com.zzyl.service.RefundRecordService;
import com.zzyl.service.TradingService;
import com.zzyl.utils.ThreadLocalUtil;
import com.zzyl.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

@Slf4j
@Service
public class BillServiceImpl implements BillService {

    @Resource
    private BillMapper billMapper;
    @Resource
    private PrepaidRechargeRecordMapper prepaidRechargeRecordMapper;
    @Autowired
    private TradingService tradingService;
    @Resource
    private RefundRecordService refundRecordService;
    @Resource
    private MemberService memberService;
    @Resource
    private MemberElderMapper memberElderMapper;
    @Autowired
    private OrderMapper orderMapper;

    @Override
    public BillVo selectByPrimaryKey(Long id) {
        Bill bill = billMapper.selectByPrimaryKey(id);
        BillVo billVo = BeanUtil.toBean(bill, BillVo.class);
        CheckInConfigVo checkInConfigVo = billVo.getCheckInConfigVo();
        BigDecimal add = checkInConfigVo.getBedCost().add(checkInConfigVo.getNursingCost()).add(checkInConfigVo.getOtherCost());
        checkInConfigVo.setAdd1(add);
        BigDecimal add1 = checkInConfigVo.getGovernmentSubsidy().add(checkInConfigVo.getMedicalInsurancePayment());
        checkInConfigVo.setAdd2(add1);
        checkInConfigVo.setMonthCost(add.subtract(add1));
        billVo.setCheckInConfigVo(checkInConfigVo);
        BigDecimal subtract = billVo.getBillAmount().subtract(billVo.getPrepaidAmount());

        // 已支付 已关闭并且应付大于0的情况 展示其他支付方式的金额
        if (billVo.getTransactionStatus().equals(1) || (billVo.getTransactionStatus().equals(2) && billVo.getPayableAmount().compareTo(new BigDecimal(0)) == 0)) {
            billVo.setOtherAmount(subtract);
        }

        if (billVo.getBillType().equals(BillType.PROJECT.getOrdinal())) {
            Trading tradByTradingOrderNo = tradingService.findTradByTradingOrderNo(billVo.getTradingOrderNo());
            if (ObjectUtil.isNotEmpty(tradByTradingOrderNo)) {
                RefundRecordVo refundRecordVo = new RefundRecordVo();
                List<RefundRecord> listByTradingOrderNo = refundRecordService.findListByTradingOrderNo(bill.getTradingOrderNo());
                if (CollUtil.isNotEmpty(listByTradingOrderNo)) {
                    refundRecordVo = BeanUtil.toBean(listByTradingOrderNo.get(0), RefundRecordVo.class);

                }
                Member byId = memberService.getById(tradByTradingOrderNo.getCreateBy());
                if (ObjectUtil.isNotEmpty(byId)) {
                    tradByTradingOrderNo.setMemberCreator(byId.getName());
                    tradByTradingOrderNo.setPhone(byId.getPhone());
                    billVo.setMemberCreator(byId.getName());
                    refundRecordVo.setCreator(byId.getName());
                }
                billVo.setRefundRecordVo(refundRecordVo);
                List<Order> orders = orderMapper.selectByTradingOrderNo(Lists.newArrayList(billVo.getTradingOrderNo()));
                if (CollUtil.isNotEmpty(orders)) {
                    billVo.setOrderId(orders.get(0).getId());
                    billVo.setOrderNo(orders.get(0).getOrderNo());
                    String format = LocalDateTimeUtil.format(orders.get(0).getCreateTime(), "yyyy-MM");
                    billVo.setBillMonth(format);
                }
                billVo.setTradingVo(Lists.newArrayList(BeanUtil.toBean(tradByTradingOrderNo, TradingVo.class)));
            }
        }
        return billVo;
    }

    /**
     * 查询欠费账单
     *
     * @param bedNo     床位号
     * @param elderName 老人姓名
     * @param pageNum   页码
     * @param pageSize  每页数量
     * @return 分页结果
     */
    @Override
    public PageBean<BillVo> arrears(String bedNo, String elderName, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        Page<BillVo> page = billMapper.arrears(bedNo, elderName);
        return PageBean.of(page, BillVo.class);
    }

    /**
     * 分页查询预交款充值记录
     *
     * @param bedNo     床位号
     * @param elderName 老人姓名
     * @param pageNum   页码
     * @param pageSize  每页数量
     * @return 分页结果
     */
    @Override
    public PageBean<PrepaidRechargeRecordVo> prepaidRechargeRecordPage(String bedNo, String elderName, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        Page<PrepaidRechargeRecord> page = prepaidRechargeRecordMapper.prepaidRechargeRecordPage(bedNo, elderName);
        return PageBean.of(page, PrepaidRechargeRecordVo.class);
    }

    /**
     * 小程序账单分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageBean<BillVo> pageQuery4Customer(BillPageQueryDto dto) {
        //如果elderId有值，就只查询该老人的账单
        //如果elderId没有值，就查询该用户关联的所有老人账单
        if (ObjectUtil.isNotEmpty(dto.getElderId())) {
            List<Long> elderId = List.of(dto.getElderId());
            //给老人Id的集合赋值，因为它是sql中的动态条件
            dto.setElderIds(elderId);
        } else {
            //获取当前用户id
            Long userId = ThreadLocalUtil.get();
            //根据用户id查询关联的老人列表
            List<MemberElder> memberElders = memberElderMapper.listByMemberId(userId);
            //提取集合中每一个对象的某一个属性值
            List<Long> elderIds = CollUtil.getFieldValues(memberElders, "elderId", Long.class);
            dto.setElderIds(elderIds);
        }

        //开启分页查询
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());

        Page<BillVo> page = billMapper.page(dto);
        return PageBean.of(page, BillVo.class);
    }

    /**
     * 管理端账单分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageBean<BillVo> pageQuery4Admin(BillPageQueryDto dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        Page<BillVo> page = billMapper.page(dto);
        return PageBean.of(page, BillVo.class);
    }
}
